/**
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.xume.solrj.dsl;

import static org.xume.solrj.criteria.criterion.Restrictions.eq;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.xume.solrj.criteria.criterion.Criterion;
import org.xume.solrj.criteria.value.Phrase;
import org.xume.solrj.criteria.value.Terms;
import org.xume.solrj.criteria.value.Value;
import org.xume.solrj.criteria.value.Values;

/**
 * @author Johan Siebens
 */
public class SolrCriteriaDsl {

	public static Fields fields(String... fields) {
		return new Fields(fields);
	}

	public static Optional firstResult(final int i) {
		return new FirstResult(i);
	}

	public static Optional maxResults(final int i) {
		return new MaxResults(i);
	}

	public static Optional orderAscBy(final String field) {
		return new Order(field, ORDER.asc);
	}

	public static Optional orderDescBy(final String field) {
		return new Order(field, ORDER.desc);
	}

	public static Value phrase(String value) {
		return new Phrase(value);
	}

	public static Query query(Criterion criterion) {
		return new Query(criterion);
	}

	public static Query query(String field, Value value) {
		return query(eq(field, value));
	}

	public static Query query(String field, String value) {
		return query(field, Values.defaultImpl(value));
	}

	public static Query query(String value) {
		return query(eq(Values.defaultImpl(value)));
	}

	public static SolrQuery solrQuery(With with) {
		SolrQuery result = new SolrQuery(with.criterion.toQueryFragment());

		String[] fields = with.fields;
		if (fields != null) {
			for (String field : fields) {
				result.addField(field);
			}
		}

		Optional[] optionals = with.optional;
		if (optionals != null) {
			for (Optional optional : optionals) {
				optional.execute(result);
			}
		}
		return result;
	}

	public static Value terms(String value) {
		return new Terms(value);
	}

	public static With with(Query query, Fields fields, Optional... optional) {
		return new With(query.criterion, fields.values, optional);
	}

	static class Fields {

		private String[] values;

		private Fields(String[] values) {
			this.values = values;
		}

	}

	static class Query {

		private Criterion criterion;

		private Query(Criterion criterion) {
			this.criterion = criterion;
		}

	}

	static class With {

		private Criterion criterion;

		private String[] fields;

		private Optional[] optional;

		private With(Criterion criterion, String[] fields, Optional[] optional) {
			this.fields = fields;
			this.criterion = criterion;
			this.optional = optional;
		}

	}

}
